<template>
    <div id="role-auth-menu">
        <el-dialog
            :title="$t('key_12')"
            v-model="isMenuDialog" 
            draggable 
            :close-on-click-modal="false" 
            width="769px" 
            :before-close="handleClose"
            :destroy-on-close="true"
            @close="clean"
        >
            <el-form :model="ruleForm" ref="ruleFormRef" size="default" label-width="auto" :rules="rules">
                <el-row>
                    <el-col :xs="20" :sm="20" :md="20" :lg="20" :xl="20" class="mb20">
                        <el-form-item :label="$t('key_30')">
                            <el-select value-key="appCode" @change="applyChange" v-model="applyVal" :placeholder="$t('key_31')">
                                <el-option
                                    v-for="item in applyOption"
                                    :key="item.appCode"
                                    :label="item.appName"
                                    :value="item"
                                >
                                </el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :xs="20" :sm="20" :md="20" :lg="20" :xl="20" class="mb20">
                        <el-form-item :label="$t('key_32')">
                            <el-tree 
                                ref="treeData"
                                :data="choseMenuList" 
                                :highlight-current="true" 
                                :default-expand-all="true" 
                                :expand-on-click-node="false" 
                                :default-checked-keys="defaultChecked"
                                node-key="id"
                                :props="defaultProps" 
                                show-checkbox
                                @check="handlCheck"
                                @check-change="handleNodeClick">
                            </el-tree>
                        </el-form-item>
                    </el-col>
                </el-row>
            </el-form>
            <template #footer>
                <el-button @click="cancelUseClick">{{ $t('key_24') }}</el-button>
                <el-button type="primary" :disabled="repeatDis" @click="submitForm(ruleFormRef)">{{ $t('key_25') }}</el-button>
            </template>
        </el-dialog>
    </div>
</template>
<script lang="ts">
import { defineComponent, nextTick , ref, reactive , computed , toRef , toRefs , toRaw , onMounted , watch, Ref } from 'vue'
import { FormInstance, FormRules , ElMessage, ElButton, ElCol, ElDatePicker, ElDialog, ElDivider, ElForm, ElFormItem, ElInput, ElOption, ElRadio, ElRow, ElSelect, ElTable, ElTableColumn } from 'element-plus'
import { getAppList } from '/@/api/system/app/index'
import { getMenuListById } from '/@/api/system/menu/index.ts'
import { sysRoleGrantMenu , sysRoleOwnMenu , SysMenuTreeForGrant } from '/@/api/manage/manage.ts'
import { forEach } from 'lodash'
/*** 定义接口基础数据类型 */
interface formType {
    repeatDis: Boolean,
    ruleForm: ruleFormType,
}
/*** form 表单数据类型 */
type ruleFormType = {}
export default defineComponent( {
    name: 'role-auth-menu',
    components: {},
    props: {
        isMenuDialog:{
            type: Boolean,
            default: false,
        },
        listId: {
            type: String,
            default: ''
        }
    },
    setup(props,ctx){
        const ruleFormRef = ref()
        const applyOption = ref()
        const applyVal = ref()
        const choseMenuList = ref()
        const defaultChecked = ref()
        let treeData: Ref = ref(null)
        // let nodeChose:any[] = []
        let preCode:any = '' // 当前应用的appCode
        let menuObj:any = {}

        const checkStrictly = ref()
        const defaultProps: object = {
            children: 'children',
            label: 'title',
        }

        /*** 基础验证 rules */
        const rules = reactive < FormRules > ({
            /*** 放置验证 */
            // name: [
			// 	{ required: true, message: '请输入角色名', trigger: 'blur' },
			// ],
        })

        /*** state 引用接口定义基础数据初始值 */
        const state = reactive < formType > ({
            repeatDis: false,
            ruleForm: {} as ruleFormType
        })

        /*** applyChange 选择应用事件 */
        const applyChange = (val:any) => {
            choseMenuList.value = val.treeInfo
            preCode = val.appCode
            if(val.defaultInfo){
                val.defaultInfo.map((val:any) => {
                    let setTime = setInterval(() => {
                        clearInterval(setTime)
                        let node = treeData.value.getNode(val)
                        if(node.isLeaf){
                            treeData.value.setChecked(node,true)
                        }
                    },200)
                })
            }
        }

        /*** handleNodeClick 树型当前节点点击事件 */
        const handleNodeClick = () => {
            let res1 = treeData.value.getCheckedKeys()
            let res2 = treeData.value.getHalfCheckedKeys()
            let choseArr = [...res1] // 子节点
            let subApi = [...res1,...res2] // 父子节点
            menuObj = {codeName:preCode,menu:choseArr,subApi:subApi}

        }

        /*** handlCheck 当节点状态改变时触发 */
        const handlCheck = () => {
            // 注意：这里是根据应用的名称来做的判断
            toRaw(applyOption.value).map((i:any) => {
                if(i.appCode === menuObj.codeName){
                    i.defaultInfo = menuObj.subApi
                }
            })
        }

        /*** handleClose 关闭按钮点击事件 */
        const handleClose = () => {
            ctx.emit('cancelMenuClick')
        }

        /*** cancelUseClick 取消事件 */
        const cancelUseClick = () => {
            ctx.emit('cancelMenuClick')
        }

        /*** submitForm 提交事件 */
        const submitForm = (formEl: FormInstance | undefined) => {
            if(!formEl) return
            formEl.validate( async (valid) => {
                if(valid){
                    let needId = toRaw(props.listId)
                    let setArr:any = []
                    toRaw(applyOption.value).map((i:any) => {
                        if(i.defaultInfo){
                            i.defaultInfo.forEach((z:any) => {
                                setArr.push(z)
                            })
                        }
                    })
                    let param = {
                        id: needId,
                        grantMenuIdList: setArr
                    }
                    try {
                        let res = await sysRoleGrantMenu(param)
                        if(res.success){
                            state.repeatDis = true
                            ctx.emit('controlMenuClick')
                            ctx.emit('updateData')
                        }else{
                            state.repeatDis = true
                            ctx.emit('controlMenuClick')
                        }
                    } catch (err) { return }
                }else{
                    console.log('error submit!')
					return false
                }
            })
        }

        /*** clean 清空数据 */
        const clean = () => {
            ruleFormRef.value.resetFields()
        }

        /*** GetAllMenuInfo 获取菜单信息(查看原框架接口设计) */
        const GetAllMenuInfo = async () => {
            try {
                let res: { data: any } = await SysMenuTreeForGrant()
                await getHaveMenu()
                if(res.data.length !== 0){
                    applyOption.value = res.data.appList
                    applyVal.value = res.data.appList[0]
                    res.data.appList.forEach((z:any) => {
                        // 显示的树菜单
                        z.treeInfo = []
                        res.data.menuTree.map((i:any) => {
                            if(i.appCode === z.appCode){
                                z.treeInfo.push(i)
                            }
                        })
                        // 默认回显的数据
                        toRaw(defaultChecked.value).map((i:any) => {
                            if(i.appCode === z.appCode){
                                z.defaultInfo = i.menuIdList
                            }
                        })
                    })
                    choseMenuList.value = res.data.appList[0].treeInfo
                    preCode = res.data.appList[0].appCode // 第一个应用的名称
                    if(res.data.appList[0].defaultInfo){
                        res.data.appList[0].defaultInfo.map((val:any) => {
                            let setTime = setInterval(() => {
                                clearInterval(setTime)
                                let node = treeData.value.getNode(val)
                                if(node.isLeaf){
                                    treeData.value.setChecked(node,true)
                                }
                            },200)
                        })
                    }
                }
                console.log(res.data.appList,'appList')
            } catch (err) {}
        }

        /*** getHaveMenu 获取用户已拥有的菜单 */
        const getHaveMenu = async () => {
            try {
                let res: { data: any[] } = await sysRoleOwnMenu({id: toRaw(props.listId)})
                if(res.data.length !== 0){
                    let getArr:any = []
                    res.data.map((i:any) => {
                        i.menuIdList.forEach((z:any) => {
                            getArr.push(z)
                        })
                    })
                    // nodeChose = getArr
                }
                defaultChecked.value = res.data
            } catch (err) {}
        }

        /*** 监听isMenuDialog的变化 */
        watch(() => props.isMenuDialog,(newVal) => {
            if(newVal){
                state.repeatDis = false
                GetAllMenuInfo() // 菜单权限数据
            }
        })

        /*** isMenuDialog 响应弹窗的关闭  */
        const isMenuDialog = computed(() => {
            return props.isMenuDialog
        })

        return {
            rules,
            defaultProps,
            handleClose,
            submitForm,
            cancelUseClick,
            clean,
            ruleFormRef,
            ...toRefs(state),
            isMenuDialog,
            applyOption,
            applyChange,
            applyVal,
            choseMenuList,
            handleNodeClick,
            treeData,
            defaultChecked,
            checkStrictly,
            handlCheck,
        }
    },
} )
</script>
<style scoped lang="scss">
    .mb20{
        margin: auto;
    }
    :deep(.el-select){
        width: 100%;
    }  
    :deep(.el-tree){
        width: 100%;
    }
</style>